Add GtkFixed demo
authorEmmanuele Bassi <ebassi@gnome.org>
Tue, 2 Apr 2019 19:49:35 +0000 (20:49 +0100)
committerEmmanuele Bassi <ebassi@gnome.org>
Tue, 2 Apr 2019 19:52:49 +0000 (20:52 +0100)
This demo has everything:

 - a GtkFixed inside another GtkFixed
 - a cube made out of GtkFrame widgets
 - an example of 3D transformations

And what's there, in the window once I launch it? The GTK logo made of
widgets.

demos/gtk-demo/demo.gresource.xml
demos/gtk-demo/fixed.c [new file with mode: 0644]
demos/gtk-demo/fixed.css [new file with mode: 0644]
demos/gtk-demo/meson.build

index 051161242cad6ba9ebf2610989792b33f70c786b..a71adcee261388b8478f339bc6991918e342efbb 100644 (file)
     <file>expander.c</file>
     <file>filtermodel.c</file>
     <file>fishbowl.c</file>
+    <file>fixed.c</file>
     <file>flowbox.c</file>
     <file>foreigndrawing.c</file>
     <file>font_features.c</file>
     <file>demotaggedentry.c</file>
     <file>demotaggedentry.h</file>
   </gresource>
+  <gresource prefix="/fixed">
+    <file>fixed.css</file>
+  </gresource>
   <gresource prefix="/org/gtk/Demo4">
     <file>icons/16x16/actions/application-exit.png</file>
     <file>icons/16x16/actions/document-new.png</file>
diff --git a/demos/gtk-demo/fixed.c b/demos/gtk-demo/fixed.c
new file mode 100644 (file)
index 0000000..745b8c7
--- /dev/null
@@ -0,0 +1,167 @@
+/* Fixed layout
+ *
+ * GtkFixed is a container that allows placing and transforming
+ * widgets manually.
+ */
+
+#include <gtk/gtk.h>
+
+/* This enumeration determines the paint order */
+enum {
+  FACE_BACK,
+  FACE_LEFT,
+  FACE_BOTTOM,
+  FACE_RIGHT,
+  FACE_TOP,
+  FACE_FRONT,
+
+  N_FACES
+};
+
+/* Map face widgets to CSS classes */
+static struct {
+  GtkWidget *face;
+  const char *css_class;
+} faces[N_FACES] = {
+  [FACE_BACK] = { NULL, "back", },
+  [FACE_LEFT] = { NULL, "left", },
+  [FACE_RIGHT] = { NULL, "right", },
+  [FACE_TOP] = { NULL, "top", },
+  [FACE_BOTTOM] = { NULL, "bottom", },
+  [FACE_FRONT] = { NULL, "front", },
+};
+
+static GtkWidget *
+create_faces (void)
+{
+  GtkWidget *fixed = gtk_fixed_new ();
+  int face_size = 200;
+  float w, h, d, p;
+
+  gtk_widget_set_overflow (fixed, GTK_OVERFLOW_VISIBLE);
+
+  w = (float) face_size / 2.f;
+  h = (float) face_size / 2.f;
+  d = (float) face_size / 2.f;
+  p = face_size * 3.f;
+
+  for (int i = 0; i < N_FACES; i++)
+    {
+      GskTransform *transform = NULL;
+
+      /* Add a face */
+      faces[i].face = gtk_frame_new (NULL);
+      gtk_widget_set_size_request (faces[i].face, face_size, face_size);
+      gtk_style_context_add_class (gtk_widget_get_style_context (faces[i].face), faces[i].css_class);
+      gtk_container_add (GTK_CONTAINER (fixed), faces[i].face);
+
+      /* Set up the transformation for each face */
+      transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (w, h));
+      transform = gsk_transform_perspective (transform, p);
+      transform = gsk_transform_rotate_3d (transform, -30.f, graphene_vec3_x_axis ());
+      transform = gsk_transform_rotate_3d (transform, 135.f, graphene_vec3_y_axis ());
+      transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0, 0, -face_size / 6.f));
+
+      switch (i)
+        {
+        case FACE_FRONT:
+          transform = gsk_transform_rotate_3d (transform, 0.f, graphene_vec3_y_axis ());
+          break;
+
+        case FACE_BACK:
+          transform = gsk_transform_rotate_3d (transform, -180.f, graphene_vec3_y_axis ());
+          break;
+
+        case FACE_RIGHT:
+          transform = gsk_transform_rotate_3d (transform, 90.f, graphene_vec3_y_axis ());
+          break;
+
+        case FACE_LEFT:
+          transform = gsk_transform_rotate_3d (transform, -90.f, graphene_vec3_y_axis ());
+          break;
+
+        case FACE_TOP:
+          transform = gsk_transform_rotate_3d (transform, 90.f, graphene_vec3_x_axis ());
+          break;
+
+        case FACE_BOTTOM:
+          transform = gsk_transform_rotate_3d (transform, -90.f, graphene_vec3_x_axis ());
+          break;
+
+        default:
+          break;
+        }
+
+      transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0, 0, d));
+      transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (-w, -h, 0));
+
+      gtk_fixed_set_child_transform (GTK_FIXED (fixed), faces[i].face, transform);
+      gsk_transform_unref (transform);
+    }
+
+  return fixed;
+}
+
+static GtkWidget *demo_window = NULL;
+static GtkCssProvider *provider = NULL;
+
+static void
+close_window (GtkWidget *widget)
+{
+  /* Reset the state */
+  for (int i = 0; i < N_FACES; i++)
+    faces[i].face = NULL;
+
+  gtk_style_context_remove_provider_for_display (gdk_display_get_default (),
+                                                 GTK_STYLE_PROVIDER (provider));
+  provider = NULL;
+
+  demo_window = NULL;
+}
+
+static GtkWidget *
+create_demo_window (GtkWidget *do_widget)
+{
+  GtkWidget *window, *sw, *fixed, *cube;
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_display (GTK_WINDOW (window),  gtk_widget_get_display (do_widget));
+  gtk_window_set_title (GTK_WINDOW (window), "Fixed layout");
+  gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
+  g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
+
+  sw = gtk_scrolled_window_new (NULL, NULL);
+  gtk_container_add (GTK_CONTAINER (window), sw);
+
+  fixed = gtk_fixed_new ();
+  gtk_container_add (GTK_CONTAINER (sw), fixed);
+  gtk_widget_set_halign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER);
+  gtk_widget_set_valign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER);
+
+  cube = create_faces ();
+  gtk_container_add (GTK_CONTAINER (fixed), cube);
+  gtk_widget_set_overflow (fixed, GTK_OVERFLOW_VISIBLE);
+
+  provider = gtk_css_provider_new ();
+  gtk_css_provider_load_from_resource (provider, "/fixed/fixed.css");
+  gtk_style_context_add_provider_for_display (gdk_display_get_default (),
+                                              GTK_STYLE_PROVIDER (provider),
+                                              800);
+  g_object_unref (provider);
+
+  return window;
+}
+
+GtkWidget*
+do_fixed (GtkWidget *do_widget)
+{
+  if (demo_window == NULL)
+    demo_window = create_demo_window (do_widget);
+
+  if (!gtk_widget_get_visible (demo_window))
+    gtk_widget_show (demo_window);
+  else
+    gtk_widget_destroy (demo_window);
+
+  return demo_window;
+}
diff --git a/demos/gtk-demo/fixed.css b/demos/gtk-demo/fixed.css
new file mode 100644 (file)
index 0000000..0e62285
--- /dev/null
@@ -0,0 +1,29 @@
+frame.front {
+  border: 2px solid white;
+  background-color: rgba(228, 0, 0, 0.8);
+}
+
+frame.back {
+  border: 2px solid white;
+  background-color: rgba(228, 0, 0, 0.8);
+}
+
+frame.right {
+  border: 2px solid white;
+  background-color: rgba(127, 231, 25, 0.8);
+}
+
+frame.left {
+  border: 2px solid white;
+  background-color: rgba(127, 231, 25, 0.8);
+}
+
+frame.top {
+  border: 2px solid white;
+  background-color: rgba(114, 159, 207, 0.8);
+}
+
+frame.bottom {
+  border: 2px solid white;
+  background-color: rgba(114, 159, 207, 0.8);
+}
index cbe956d0c23d9f63ba3652b4f8079727d06a9726..aba44c976ce923e5a3d22f8568bb0c371667ba5a 100644 (file)
@@ -24,6 +24,7 @@ demos = files([
   'expander.c',
   'filtermodel.c',
   'fishbowl.c',
+  'fixed.c',
   'foreigndrawing.c',
   'gestures.c',
   'glarea.c',